package io.task.cc.network.utils.lock;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

/**
 * 自带读写锁的对象.
 */
@Slf4j
@Setter
@Getter
public class LockedObject<T> {


    private T t;


    private ReentrantReadWriteLock lock;


    public LockedObject(T t) {
        this(t, new ReentrantReadWriteLock());
    }


    public LockedObject(T t, ReentrantReadWriteLock lock) {
        super();
        this.t = t;
        this.lock = lock;
    }


    /**
     * 获取写锁
     */
    public WriteLock writeLock() {
        return lock.writeLock();
    }

    /**
     * 获取读锁
     */
    public ReadLock readLock() {
        return lock.readLock();
    }

    /**
     * 操作obj时，带上写锁
     */
    public void handle(WriteLockHandler<T> writeLockHandler) {
        WriteLock writeLock = lock.writeLock();
        writeLock.lock();
        try {
            writeLockHandler.handle(t);
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
        } finally {
            writeLock.unlock();
        }
    }


    /**
     * 操作obj时，带上读锁
     */
    public void handle(ReadLockHandler<T> readLockHandler) {
        ReadLock readLock = lock.readLock();
        readLock.lock();
        try {
            readLockHandler.handle(t);
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
        } finally {
            readLock.unlock();
        }
    }


}
